
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
    mode: 'development',
    devtool: false,
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'main.js'
    },
    // babel-polyfill 它是通过向全局对象和内置对象的prototype上添加方法来实现的。
    // 比如运行环境中不支持Array.prototype.find方法，引入polyfill, 我们就可以使用ES6方法来编写了，
    // 缺点就是会造成全局空间污染
    module: {
        rules: [
            {
                test:/\.js$/,
                exclude: /node_modules/,
                use:{
                    loader: 'babel-loader',
                    options:{
                        targets:{ //表示我们需要支持哪些平台和哪些版本
                            "browsers": ["IE 6"]
                        },
                        presets: [
                            ["@babel/preset-env", { 
                                //@babel/preset-env默认只支持ES6语法转化,需要开启useBuiltIns配置才能转化API和实例方法

                                // useBuiltIns可选值包括："usage" | "entry" | false, 默认为 false，

                                // 1.false则需要在使用的模块中手动引入polyfill，把polyfill全量引入，不考虑浏览器兼容性 
                                // useBuiltIns: false

                                // 2.entry 根据配置的浏览器兼容，引入浏览器不兼容的 polyfill。
                                // 需要在入口文件手动添加 import '@babel/polyfill'（多次引入会报错），会自动根据 browserslist 替换成浏览器不兼容的所有 polyfill
                                // 如果使用useBuiltIns: 'entry',则必须指定corejs版本号。corejs其实就是 polyfill方法的实现。corejs默认版本号是2,
                                // 如果配置 corejs: 3, 则import '@babel/polyfill' 需要改成 import 'core-js/stable';import 'regenerator-runtime/runtime'; 
                                // useBuiltIns: "entry",
                                // corejs:{version:3}

                                // 3.usage 会根据配置的浏览器兼容，以及你代码中用到的 API 来进行 polyfill，实现了按需添加
                                // 当设置为usage时，polyfill会自动按需添加，不再需要手工引入@babel/polyfill
                                // 如果使用usage，那么在编译的时候webpack会判断你是否用到了某个新的API，并且会考虑你配置的浏览器兼容性，来确定单个引个此API对应的polyfill
                                // useBuiltIns: "usage",
                                // corejs: { version: 3 } //原理就是Array.prototype.find = corejs自己提供的find方法，但是会污染全局变量
                            }]
                            /* 
                            注意点：
                            @babel/preset-env和useBuiltIns提供的polyfill会污染全局环境，因此我们可以不采用。
                            而是使用babel-runtime来提供polyfill解决全局空间污染的问题。
                            简单说 babel-runtime 更像是一种按需加载的实现，比如你哪里需要使用 Promise，只要在这个文件头部import Promise from 'babel-runtime/core-js/promise'就行了
                            缺点：容易重复引用 
                            */
                        ],
                        /* 
                        @babel/plugin-transform-runtime插件是为了解决2个问题：
                            1.多个文件重复引用 相同helpers(帮助函数)=>提取运行时
                            2.新API方法全局污染 -> 局部引入 
                        */
                        plugins:[
                            ["@babel/plugin-transform-runtime",{
                                corejs: 3,
                                helpers: true, //移除内联babel helpers并替换使用babel-runtime/helpers 来替换,避免内联的 helper 代码在多个文件重复出现
                                regenerator: true //是否开启generator函数转换成使用regenerator runtime来避免污染全局域
                            }]
                        ]
                        /* 
                        启用插件babel-plugin-transform-runtime后，Babel就会使用babel-runtime下的工具函数
                        babel-plugin-transform-runtime插件能够将这些工具函数的代码转换成require语句，指向为对babel-runtime的引用
                        babel-plugin-transform-runtime 就是可以在我们使用新 API 时自动 import babel-runtime 里面的 polyfill
                            当我们使用 async/await 时，自动引入 babel-runtime/regenerator
                            当我们使用 ES6 的静态事件或内置对象时，自动引入 babel-runtime/core-js
                            移除内联babel helpers并替换使用babel-runtime/helpers 来替换 
                        */
                    }
                    
                }
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/index.html'
        })
    ]
};

